package com.alex.program;

/**
 * 给你两个 非空 的链表，表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的，并且每个节点只能存储 一位 数字。
 *
 * 请你将两个数相加，并以相同形式返回一个表示和的链表。
 *
 * 你可以假设除了数字 0 之外，这两个数都不会以 0 开头。
 */
public class 两数相加_2 {

    public static void main(String[] args) {
        两数相加_2 call = new 两数相加_2();
        ListNode node = call.addTwoNumbers(new ListNode(2, new ListNode(4, new ListNode(3))), new ListNode(5, new ListNode(6, new ListNode(4))));
    }

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        // 虚拟头结点(保证头节点位置固定)
        ListNode dummy = new ListNode(-1);
        // 实际操作节点.
        ListNode head = new ListNode(0);
        // 虚拟头节点和实际头节点连接在一起
        dummy.next = head;

        int addNextValue = 0;
        // 循环终止条件分析: 只要有任意一个链表或者进位数据, 都应该再算一遍;
        while (l1 != null || l2 != null || addNextValue > 0) {
            // 进位数据节点: 需要每次参数运算.
            int sum = head.val;

            if (l1 != null) {
                sum += l1.val;
                l1 = l1.next;
            }

            if (l2 != null) {
                sum += l2.val;
                l2 = l2.next;
            }

            // 进位标识
            addNextValue = sum / 10;
            // 余数
            head.val = sum % 10;

            if (l1 != null || l2 != null || addNextValue > 0) {
                // 进位作为下一次和L1 + L2的参数一起运算
                head.next = new ListNode(addNextValue);
                // 指针调节到下一个节点(也就是上一行的进位数据节点);
                head = head.next;
            }

            // 当两个链表都遍历完成之后, 上一步骤也加入了最后一个进位node; 可以直接退出
            if (l1 ==null && l2 == null) {
                break;
            }
        }

        return dummy.next;

    }
}
